/*
 * core.h
 *
 *  (c) by Normen Seemann
 *
 *  Created on: May 1, 2009
 *
 */

#ifndef EXCEPTIONS_H_
#define EXCEPTIONS_H_

#include <string>
#include <stdio.h>
#include <signal.h>

namespace crossEyed
{
namespace core
{

using namespace std ;

//
// TException
//
class TException
{
protected:
   const char *  pFuncName ;
   unsigned int  line ;

public:
   TException( const char * pFuncName, unsigned int line )
      : pFuncName( pFuncName), line( line )
   {
      //
      // We cannot get memory for storing the reason, we might be just here because
      // we are low on memory.
      //
   } ;

   virtual void print(FILE *f) ;

   ~TException() { } ;
};

//
// TAssertion
//
class TAssertion : public TException
{
protected:
   const char *pExpression ;

public:
   TAssertion( const char * pFuncName, unsigned int line , const char *pExpression)
     : TException( pFuncName, line ), pExpression( pExpression )
   {
   } ;

   ~TAssertion() { } ;

   virtual void print(FILE *f) ;

   inline void raise()
   {
      ::raise( SIGABRT ) ;
   }
};

//
// TOOMemoryException
//
class TOOMemoryException : public TException
{
public:
   TOOMemoryException( const char * pFuncName, unsigned int line )
     : TException( pFuncName, line )
   {
   } ;

   ~TOOMemoryException() { } ;

   virtual void print(FILE *f) ;

   inline void raise()
   {
      ::raise( SIGABRT ) ;
   }
};

//
// TIOException
//
class TIOException: public TException
{
protected:
   string fileName;
   int    errNo ;

public:
   TIOException( const char * pFileName,
                 int          errNo,
                 const char * pFuncName,
                 unsigned int line )
      : TException( pFuncName, line ), fileName( pFileName), errNo( errNo )
   {} ;

   virtual void print(FILE *f) ;
};

//
// TError
//
class TError : public TException
{
protected:
   const char *pErrorMessage ;

public:
   TError( const char * pFuncName, unsigned int line , const char *pErrorMessage)
     : TException( pFuncName, line ), pErrorMessage( pErrorMessage )
   {
   } ;

   ~TError() { } ;

   virtual void print(FILE *f) ;

   inline void raise()
   {
      ::raise( SIGABRT ) ;
   }
};

#if defined XI_DEBUG
#define XI_ASSERT_HARD( expr ) \
   if ( !( expr ) ) \
   { \
      using namespace crossEyed::core ; \
      TAssertion a( const_cast<char *>( __FUNCTION__ ), __LINE__, const_cast<char *>( #expr ) ) ; \
      a.print( stderr ) ; \
      a.raise( ) ; \
   }

#define XI_OOM_HARD \
   { \
      using namespace crossEyed::core ; \
      TOOMemoryException e( const_cast<char *>( __FUNCTION__ ), __LINE__ ) ; \
      e.print( stderr ) ; \
      e.raise( ) ; \
   }

#define XI_ASSERT_FAST( expr ) \
   if ( !( expr ) ) \
   { \
      using namespace crossEyed::core ; \
      throw TAssertion( const_cast<char *>( __FUNCTION__ ), __LINE__, const_cast<char *>( #expr ) ) ; \
   }
#else
#define XI_OOM_HARD
#define XI_ASSERT_HARD( expr )
#define XI_ASSERT_FAST( expr )
#endif

}}
#endif /* EXCEPTIONS_H_ */
